﻿using System;
using System.Linq;
using System.Timers;

using J2N.Collections.Generic;


namespace iTool.Cloud.DataSearch.ServiceProvider
{
    //class LockTime { public LockTime(DateTime dateTime) { this.DateTime = dateTime; } public DateTime DateTime { get; set; } }
    public class IDirectoryServiceFactory<TType>
        where TType : IFactoryService, new()
    {
        //static Dictionary<string, LockTime> lookDic;
        static Dictionary<string, TType> objectPool;
        static Dictionary<string, DateTime> objectPoolLastGet;
        static IDirectoryServiceFactory()
        {
            //lookDic = new Dictionary<string, LockTime>();
            objectPool = new Dictionary<string, TType>();
            objectPoolLastGet = new Dictionary<string, DateTime>();
            var timer = new System.Timers.Timer(1000 * 10);
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            timer.Start();
        }

        static void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            
            // 清除过期的Service
            try
            {
                lock (objectPool)
                {
                    var keys = objectPoolLastGet.Where(item => ((DateTime.Now - item.Value).TotalSeconds > 120));
                    foreach (var item in keys)
                    {
                        objectPool[item.Key].FlushAsync().Wait();
                        objectPool.Remove(item.Key);
                        objectPoolLastGet.Remove(item.Key);
                    }

                    //var keys2 = lookDic.Where(item => ((DateTime.Now - item.Value.DateTime).TotalSeconds > 120));
                    //foreach (var item in keys2)
                    //{
                    //    lookDic.Remove(item.Key);
                    //}
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

        public static TType GetService(long hash, string name)
        {
            string dicKey = string.Format("{0}_{1}", hash, name);
            if (objectPool.TryGetValue(dicKey, out TType result))
            {
                objectPoolLastGet[dicKey] = DateTime.Now;
                return result;
            }

            lock (objectPool)
            {
                if (objectPool.TryGetValue(dicKey, out result))
                {
                    objectPoolLastGet[dicKey] = DateTime.Now;
                    //if (lookDic.ContainsKey(dicKey)) lookDic.Remove(dicKey);
                    return result;
                }

                result = new TType();
                //Console.WriteLine("GetService1:" + result.GetType().FullName);
                result.OnActivateAsync(hash, name);
                //Console.WriteLine("GetService2:" + result.GetType().FullName);

                if (!objectPool.ContainsKey(dicKey))
                    objectPool.Add(dicKey, result);
                if (!objectPoolLastGet.ContainsKey(dicKey))
                    objectPoolLastGet.Add(dicKey, DateTime.Now);
                //if(lookDic.ContainsKey(dicKey)) 
                //    lookDic.Remove(dicKey);
                return result;
            }
        }

        //public static TType GetService(long hash, string name)
        //{
        //    string dicKey = string.Format("{0}_{1}", hash, name);
        //    if (objectPool.TryGetValue(dicKey, out TType result))
        //    {
        //        objectPoolLastGet[dicKey] = DateTime.Now;
        //        return result;
        //    }

        //    if (!lookDic.TryGetValue(dicKey,out _))
        //    {
        //        lookDic.TryAdd(dicKey, new LockTime(DateTime.Now));
        //    }

        //    lock (lookDic[dicKey])
        //    {
        //        if (objectPool.TryGetValue(dicKey, out result))
        //        {
        //            objectPoolLastGet[dicKey] = DateTime.Now;
        //            //if (lookDic.ContainsKey(dicKey)) lookDic.Remove(dicKey);
        //            return result;
        //        }

        //        result = new TType();
        //        result.OnActivateAsync(hash, name);
        //        if (!objectPool.ContainsKey(dicKey))
        //            objectPool.Add(dicKey, result);
        //        if (!objectPoolLastGet.ContainsKey(dicKey))
        //            objectPoolLastGet.Add(dicKey, DateTime.Now);
        //        //if(lookDic.ContainsKey(dicKey)) 
        //        //    lookDic.Remove(dicKey);
        //        return result;
        //    }
        //}

        public static void Dispose(long hash, string name)
        {
            string dicKey = string.Format("{0}_{1}", hash, name);
            //lock (objectPool)
            //{
            //    if (objectPool.ContainsKey(dicKey))
            //    {
            //        objectPool[dicKey].FlushAsync().Wait();
            //        objectPool.Remove(dicKey);
            //    }
            //}
        }
    }
}
